package tfts

type State int

const (
	noopS State = iota
	NoAttack
	NoRegen
	NoCast
	LockSpeed
)

type StatusI interface {
	validI
	canCast() bool
	canAttack() bool
	canRegen() bool
	speedValid() bool
	transformRate() int
}

type Status struct {
	*buff
	NoRegen   bool // 状态期间不能自动回蓝
	NoAttack  bool // 状态期间不能攻击
	NoCast    bool // 状态期间无法施法
	LockSpeed bool // 状态期间攻速锁定
	AsToAd    int  // 锁攻速后，攻速转攻击的倍率
}

func (f *Fight) EnableMovementCost() {
	NewAction(f).Repeat(5, 3).On(TimeGoE).AddCall("Moving", func(fight *Fight) {
		f.Enter(TimeGoE, 1, NoAttack)
	})
}

func (f *Fight) Enter(event Event, duration int, states ...State) *Status {
	ret := &Status{buff: &buff{}}
	ret.buffMeta = NewBuff(event, duration)
	for _, s := range states {
		switch s {
		case LockSpeed:
			ret.LockSpeed = true
		case NoRegen:
			ret.NoRegen = true
		case NoAttack:
			ret.NoAttack = true
		case NoCast:
			ret.NoCast = true
		}
	}
	ret.buff = ret.attach(f)
	f.states = append(f.states, ret)
	return ret
}

func (f *Fight) regenAllowed() int {
	for _, s := range f.states {
		if s.valid() && !s.canRegen() {
			return 0
		}
	}
	return 1
}

func (f *Fight) attackAllowed() int {
	for _, s := range f.states {
		if s.valid() && !s.canAttack() {
			return 0
		}
	}
	return 1
}

func (f *Fight) canCast() bool {
	for _, s := range f.states {
		if s.valid() && !s.canCast() {
			return false
		}
	}
	return true
}

func (f *Fight) lockSpeed() bool {
	for _, s := range f.states {
		if s.valid() && !s.speedValid() {
			return true
		}
	}
	return false
}

func (f *Fight) transformRate() float64 {
	for _, s := range f.states {
		// 默认只有一种攻速转攻击力的效果
		if s.valid() && s.transformRate() > 0 {
			return float64(s.transformRate()) / 100
		}
	}
	return 0
}

func (s *Status) canAttack() bool {
	return !s.NoAttack
}

func (s *Status) canRegen() bool {
	return !s.NoRegen
}

func (s *Status) canCast() bool {
	return !s.NoCast
}

func (s *Status) speedValid() bool {
	return !s.LockSpeed
}

func (s *Status) transformRate() int {
	return s.AsToAd
}

func (s *Status) Attr(attrs ...*attrMeta) *Status {
	for _, a := range attrs {
		s.Add(a)
	}
	return s
}
